<?php

namespace App\Models;

use App\Models\BaseModel;

// use SimpleSoftwareIO\QrCode\Generator;
use Illuminate\Filesystem\Filesystem;
use DB;

use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Response\QrCodeResponse;

class Order extends BaseModel
{
    protected $primaryKey = 'order_id';

    protected $casts = [
        'created_at' => 'Y-m-d H:i:s',
        'updated_at' => 'Y-m-d H:i:s',
    ];

    protected $guarded = [];

    protected $appends = ['order_status','member_address', 'payment_code_name', 'created_at', 'updated_at'];

    /**
     * 订单详情
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function detail()
    {
        return $this->hasMany(OrderDetail::class, 'order_id')->with(['goods']);
    }

    /**
     * 会员信息
     * @return \Illuminate\Database\Eloquent\Relations\belongsTo
     */
    public function member()
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    /**
     * 发货信息
     * @return \Illuminate\Database\Eloquent\Relations\hasMany
     */
    public function delivery()
    {
        return $this->hasMany(Delivery::class, 'order_bn', 'order_bn');
    }

    /**
     * 地址信息
     * @return \Illuminate\Database\Eloquent\Relations\hasOne
     */
    public function address()
    {
        return $this->hasOne(MemberAddress::class, 'id', 'address_id');
    }

    /**
     * 商品图片列表
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function image()
    {
        return $this->belongsToMany(GoodsImage::class, OrderDetail::class, 'order_id', 'goods_id', 'order_id', 'goods_id');
    }

    public function getPaymentCodeNameAttribute()
    {
        $payment_arr = [
            'sumpay' => '统统付',
            'lianlianpay' => '连连付-小程序',
            'lianlpay_offline' => '连连付-线下',
        ];

        $paymentCodeName = '';
        if (isset($this->attributes['payment_code']) && $this->attributes['payment_code'])
        {
            $paymentCodeName = $payment_arr[$this->attributes['payment_code']] ?? '-';
        }
        return $paymentCodeName ?? '-';
    }

    public function getMemberAddressAttribute()
    {
        $member_address = '';
        if (isset($this->attributes['address_id']))
        {
            $address_id = $this->attributes['address_id'];

            $address = MemberAddress::where('id', $address_id)->first();

            if ($address)
            {
                if (isset($address->province) && $address->province)
                {
                    $region = Region::where('code', $address->province)->first();

                    if (isset($region->name))
                    {
                        $member_address .= $region->name;
                    }
                }

                if (isset($address->city) && $address->city)
                {
                    $region = Region::where('code', $address->city)->first();

                    if (isset($region->name))
                    {
                        $member_address .= ' '.$region->name;
                    }
                }

                if (isset($address->district) && $address->district)
                {
                    $region = Region::where('code', $address->district)->first();

                    if (isset($region->name))
                    {
                        $member_address .= ' '.$region->name;
                    }
                }

                $member_address .= ' '.$address->address;
            }
        }


        return $member_address ?? '-';
    }


    public function getOrderStatusAttribute()
    {
        $order_status = '';

        if (isset($this->attributes['status']))
        {
            switch ($this->attributes['status']) {
                case 'active':
                    if ($this->attributes['pay_status']=='notpay')
                    {
                        $order_status = '待支付';
                    }
                    if ($this->attributes['pay_status']=='paid' && $this->attributes['ship_status']=='notdelivery')
                    {
                        $order_status = '待发货';
                    }
                    if ($this->attributes['pay_status']=='paid' && $this->attributes['ship_status']=='shipped')
                    {
                        $order_status = '已完成';
                    }
                    if ($this->attributes['pay_status']=='paid' && $this->attributes['ship_status']=='returned')
                    {
                        $order_status = '已退还';
                    }
                    if ($this->attributes['pay_status']=='refunded')
                    {
                        $order_status = '已退还';
                    }
                    break;
                case 'invalid':
                    $order_status =  '已作废';
                    break;
                default:
                    $order_status =  '已完成';
                    break;
            }
        }

        return $order_status;
    }

    public function getCreatedAtAttribute()
    {
        if (isset($this->attributes['created_at']))
        {
            return date('Y-m-d H:i:s', strtotime($this->attributes['created_at']));
        }
    }

    public function getUpdatedAtAttribute()
    {
        if (isset($this->attributes['updated_at']))
        {
            return date('Y-m-d H:i:s', strtotime($this->attributes['updated_at']));
        }
    }

    public static function getList(array $attributes)
    {
        extract($attributes);

        $member =  \Auth::guard('member')->user();

        $where = ['member_id' => $member->member_id];

        switch ($status) {
            case '0': // 已支付
                $where['status'] = 'active';
                $where['pay_status'] = 'notpay';
                $where['ship_status'] = 'notdelivery';
                break;
            case '1': // 已支付
                $where['status'] = 'active';
                $where['pay_status'] = 'paid';
                $where['ship_status'] = 'notdelivery';
                break;
            case '2': // 已发货
                $where['status'] = 'done';
                $where['pay_status'] = 'paid';
                $where['ship_status'] = 'shipped';
                break;
            case '3': // 已作废
                $where['status'] = 'invalid';
                break;
            default:
                break;
        }

        $model = Order::where($where);

        $total = $model->count();

        $model->orderBy('updated_at', 'DESC');

        if (isset($per_page))
        {
            $model->with('detail');
            $data = $model->paginate($per_page)->toArray();
            if ($data['data'])
            {
                foreach ($data['data'] as $key=>$val)
                {
                    if (!$val) continue;
                    $data['data'][$key]['created_at'] = date('Y-m-d H:i:s', strtotime($val['created_at']));
                    $data['data'][$key]['updated_at'] = date('Y-m-d H:i:s', strtotime($val['updated_at']));
                }
            }

            return self::formatBody(['list' => $data['data'], 'paged' => self::formatPaged($page, $per_page, $total)]);
        }
        else
        {
            $model->with('detail');
            $data = $model->get()->toArray();
            if ($data)
            {
                foreach ($data as $key=>$val)
                {
                    if (!$val) continue;
                    $data[$key]['created_at'] = date('Y-m-d H:i:s', strtotime($val['created_at']));
                    $data[$key]['updated_at'] = date('Y-m-d H:i:s', strtotime($val['updated_at']));
                }
            }

            return self::formatBody(['list' => $data]);
        }
    }

    public static function getInfo(array $attributes)
    {
        extract($attributes);

        $member =  \Auth::guard('member')->user();

        $where = ['member_id' => $member->member_id, 'order_id' => $order_id];

        $model = Order::where($where)->with(['detail', 'address'])->first();

        if (!$model)
        {
            return self::formatError(404, '获取订单信息失败');
        }

        $info = $model->toArray();

        return self::formatBody(['detail' => $info]);
    }

    public static function toDelivery(array $attributes)
    {
        extract($attributes);

        $where = ['exchange_code' => $exchange_code];

        $model = Order::where($where)->first();

        $user =  \Auth::guard('member')->user();

        if (!$model)
        {
            return self::formatError(404 , '获取订单信息失败');
        }

        if ($model->status == 'invalid')
        {
            return self::formatError(400 , '订单已经是作废状态，无法核销');
        }

        if ($model->status == 'done')
        {
            return self::formatError(400 , '订单已经是完成，无法操作');
        }

        if ($model->ship_status == 'shipped')
        {
            return self::formatError(400 , '订单已经核销完成，请勿重复操作');
        }

        // 去核销
        $model->status = 'done';
        $model->ship_status = 'shipped';
        $model->delivery_time = date('Y-m-d H:i:s', time());
        $model->save();

        $member_bind = MemberBindAdmin::where('member_id', $user->member_id)->first();

        $users_model = config('admin.database.users_model');

        $admin = $users_model::where('id', $member_bind->admin_id)->first();

        // 记录订单核销日志
        OrderLog::create([
            'order_id' => $model->order_id,
            'order_bn' => $model->order_bn,
            'source' => 'admin',
            'op_id' => $admin->id,
            'op_name' => $admin->name,
            'member_id' => $model->member_id,
            'behavior' => OrderLog::ORDER_DELIVERY,
            'status' => 'success',
            'content' => '扫码核销订单',
        ]);

        return self::formatBody([]);
    }

    public static function create(array $attributes, &$msg='')
    {
        extract($attributes);
        foreach ($goods as $key=>$val)
        {
            // 获取商品信息
            $goodsInfo = Goods::where('id', $val['goods_id'])->with(['skus'])->first();
            // dd($goods->toArray());
            if (!$goodsInfo)
            {
                $msg = '商品不存在';
                return false;
            }

            $sku = [];
            $stock = [];
            foreach ($goodsInfo->skus as $skey=>$sval)
            {
                if ($sval['id'] == $val['sku_id'] && $sval['status']==1)
                {
                    $sku[$sval['id']] = $sval;
                }
            }

            if (!$sku)
            {
                $msg = '货品不存在';
                return false;
            }

            // 验证库存
            if ($sku[$val['sku_id']]['stock']['quantity'] < $val['num'])
            {
                $msg = '货品'.$sku[$val['sku_id']]['name'].'库存不足';
                return false;
            }

            // 验证收货地址
            $memberAddress = MemberAddress::where('id', $address_id)->first();
            if (!$memberAddress)
            {
                $msg = "收货地址错误";
                return false;
            }

            // 验证支付方式
            $check_payment = 0;
            $setting = Setting::where('code', 'payment_'.$payment_code)->first();
            if (isset($setting->value))
            {
                $payment_sumpay = json_decode($setting->value, 1);

                if (isset($payment_sumpay['open']) && ($payment_sumpay['open'] ==1))
                {
                    $check_payment = 1;
                }
            }

            if (!$check_payment)
            {
                $msg = "支付方式未开启";
                return false;
            }

            //组织订单数据
            $orderItemData[$key] = [
                'goods_id' => $val['goods_id'],
                'sku_id' => $val['sku_id'],
                'goods_name' => $sku[$val['sku_id']]['name'],
                'num' => $val['num'],
                'goods_price' => $sku[$val['sku_id']]['price'] * $val['num'],
            ];
        }

        DB::beginTransaction();

        // 此处应该走事务
        try {

            $goods_price = array_column($orderItemData, 'goods_price');

            // 创建订单
            $order = new Order;
            $order->order_bn = self::getOrderNo();
            $order->member_id = $member->member_id;
            $order->status = 'active';
            $order->pay_status = 'notpay';
            $order->ship_status = 'notdelivery';
            $order->goods_price = array_sum($goods_price);
            $order->amount = array_sum($goods_price);
            $order->remark = isset($remark) ? $remark : '';
            $order->address_id = intval($address_id);
            $order->payment_code = $payment_code;
            $res = $order->save();

            if (!$res)
            {
                $msg = "创建订单失败";
                return false;
            }

            foreach ($orderItemData as $okey => $oval)
            {
                // 创建订单明细
                $orderDetail = new OrderDetail;
                $orderDetail->order_id = $order->order_id;
                $orderDetail->goods_id = $oval['goods_id'];
                $orderDetail->sku_id = $oval['sku_id'];
                $orderDetail->goods_name = $oval['goods_name'];
                $orderDetail->num = $oval['num'];
                $orderDetail->goods_price = $oval['goods_price'];
                $orderDetail->save();

                // 扣减库存
                GoodsSkuStock::where('goods_id', $oval['goods_id'])->where('sku_id', $oval['sku_id'])->decrement('quantity', intval($oval['num']));
            }


            // 记录订单日志
            $orderLog = new OrderLog;
            $orderLog->order_id = $order->order_id;
            $orderLog->member_id = $order->member_id;
            $orderLog->order_bn = $order->order_bn;
            $orderLog->source = 'member';
            $orderLog->op_id = $member->member_id;
            $orderLog->op_name = $member->nickname;
            $orderLog->behavior = OrderLog::ORDER_CHANGE;
            $orderLog->status = 'success';
            $orderLog->content = '会员创建订单';
            $orderLog->save();

            // 购物车下单
            if ($type=='cart')
            {
                // 购物车下单 删除购物车数据
                $cartData = Cart::where('member_id', $member->member_id)->get();
                // dd($cartData->toArray(), $goods);
                foreach ($cartData as $ckey => $cval)
                {
                    foreach ($goods as $gkey => $gval)
                    {

                        if ($cval->goods_id==$gval['goods_id'] && $cval->sku_id==$gval['sku_id'])
                        {
                            // dd($cval->goods_id, $cval->sku_id);
                            $cval->delete();
                        }
                    }
                }

            }

            DB::commit();

        } catch (\Exception $exception) {

            DB::rollback();

            $msg = '订单创建失败:'.$exception->getMessage();
            return false;
        }

        return $order;

    }

    public static function getPrice(array $attributes, &$msg='')
    {
        extract($attributes);

        $total_amonut = 0;
        $goods_num = 0;
        foreach ($goods as $key=>$val)
        {
            // 获取商品信息
            $goodsInfo = Goods::where('id', $val['goods_id'])->with(['skus'])->first();
            // dd($goods->toArray());
            if (!$goodsInfo)
            {
                $msg = '商品不存在';
                return false;
            }

            $sku = [];
            $stock = [];
            foreach ($goodsInfo->skus as $skey=>$sval)
            {
                if ($sval['id'] == $val['sku_id'] && $sval['status']==1)
                {
                    $sku[$sval['id']] = $sval;
                }
            }

            if (!$sku)
            {
                $msg = '货品不存在';
                return false;
            }

            // 验证库存
            if ($sku[$val['sku_id']]['stock']['quantity'] < $val['num'])
            {
                $msg = '货品'.$sku[$val['sku_id']]['name'].'库存不足';
                return false;
            }

            $goods_num += $val['num'];
            $total_amonut += $sku[$val['sku_id']]['price'] * $val['num'];
        }

        $result = [
            'total_amonut' => sprintf('%.2f', $total_amonut),
            'discount_amount' => sprintf('%.2f', 0),
            'freight_amount' => sprintf('%.2f', 0),
            'goods_num' => $goods_num,
        ];

        return $result;
    }

    public static function cancel(array $attributes, &$msg='')
    {
        extract($attributes);

        DB::beginTransaction();

        // 此处应该走事务
        try {

            $order = Order::where('member_id', $member->member_id)->where('order_bn', $order_bn)->where('status', 'active')->where('pay_status', 'notpay')->first();

            if (!$order)
            {
                $msg = "取消失败：订单状态异常，请联系管理员";
                return false;
            }

            $order->status = 'invalid';
            $res = $order->save();

            if (!$res)
            {
                $msg = "订单取消失败";
                return false;
            }

            // 记录订单日志
            $orderLog = new OrderLog;
            $orderLog->order_id = $order->order_id;
            $orderLog->member_id = $order->member_id;
            $orderLog->order_bn = $order->order_bn;
            $orderLog->source = 'member';
            $orderLog->op_id = $member->member_id;
            $orderLog->op_name = $member->nickname;
            $orderLog->behavior = OrderLog::ORDER_INVALID;
            $orderLog->status = 'success';
            $orderLog->content = '会员取消订单';
            $orderLog->save();

            DB::commit();
        } catch (\Exception $exception) {

            DB::rollback();

            $msg = '订单取消失败:'.$exception->getMessage();
            return false;
        }

        return true;
    }

    // 获取订单号
    static function getOrderNo()
    {
        $order_bn = date('YmdH').rand(000,999);

        $count = Order::where('order_bn', $order_bn)->count();

        if ($count > 0) self::getOrderNo();

        return $order_bn;
    }

    // 统计订单数量
    public  static function getOrderNum($type, $params=[])
    {
        switch ($type)
        {
            case 'day':
                $start_time = date('Y-m-d 00:00:00', time());
                $end_time = date('Y-m-d 23:59:59', time());
                break;
            case 'week':
                $start_time = date('Y-m-d 00:00:00', strtotime('-1 week'));
                $end_time = date('Y-m-d H:i:s', time());
                break;
            case 'month':
                $start_time = date('Y-m-d 00:00:00', strtotime('-1 month'));
                $end_time = date('Y-m-d H:i:s', time());
                break;
            default:
                $start_time = date('Y-m-d 00:00:00', strtotime($params['start_time']));
                $end_time = date('Y-m-d 23:59:59', strtotime($params['end_time']));
                break;
        }

        // $start_time = date('Y-m-d 00:00:00', strtotime($params['start_time']));
        // $end_time = date('Y-m-d 23:59:59', strtotime($params['end_time']));

        $days = parent::getCountDays(strtotime($start_time), strtotime($end_time));

        $report = [];

        foreach ($days as $val)
        {
            $orderModel = self::select(DB::raw('count(order_id) as total_count'));

            $start_time = date('Y-m-d 00:00:00', strtotime($val));
            $end_time = date('Y-m-d 23:59:59', strtotime($val));

            $orderModel->whereDate('created_at', '>=', $start_time);
            $orderModel->whereDate('created_at', '<=', $end_time);

            $orderData = $orderModel->first()->toArray();

            $val = date('m-d', strtotime($val));

            $report['total_count'][$val] = $orderData['total_count'] ? $orderData['total_count'] : 0;
        }

        $label = array_values($days);
        foreach ($label as $k=>$v)
        {
            $v = date('m-d', strtotime($v));
            $label[$k] = $v;
        }

        $result = [
            'label' => $label,
            'report' => $report['total_count']
        ];

        //dd($result);
        return $result;

    }

}
